﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.IO;

namespace FBDMaker
{
    public class FBDInf
    {

        

        public FBDInf()
        {
            //Avtor = new List<LibPerson>();
            Avtor = new ObservableCollection<LibPerson>();
            _Title = new LibLang();
            _Theme = new GenreList();
            _Annot = new LibAnnot();
            _Tag = new ObservableCollection<string>();
            d_BookDate = null;
            s_BookDate = string.Empty;
            Cover = new LibCover();
            _Lang = new LibLang();
            BookSequence = new ObservableCollection<LibSequence>();
            PublishSequence = new ObservableCollection<LibSequence>();
            FileInf = new LibFileInf();
            Publisher = new LibPublisher();
        }
        public ObservableCollection <LibPerson> Avtor {get;private set;}
        //public List<LibPerson> Avtor { get; private set; }
        public LibLang         _Title { get; private set; }
        public GenreList        _Theme { get; private set; }
        public LibAnnot        _Annot {get;private set;}
        public ObservableCollection<string> _Tag { get; private set; }
        public DateTime?       d_BookDate    { get; set; }
        public string          s_BookDate { get; set; }
        public LibCover        Cover       { get; private set; }
        public LibLang         _Lang        { get; private set; }
        public ObservableCollection<LibSequence> BookSequence { get; private set; }
        public ObservableCollection<LibSequence> PublishSequence { get; private set; }
        public LibFileInf      FileInf     { get; private set; }
        public LibPublisher    Publisher   { get; private set; }
        public string Annot
        {
            get { return _Annot.Text; }
            set { _Annot.Text=value; }
        }
        public string Title
        {
            get{ return _Title.BookLang;}
            set{_Title.BookLang = value;}
        }
        public string Lang
        {
            get{return _Lang.BookLang;}
            set{_Lang.BookLang = value;}
        }
        public string TitleScr
        {
            get{return _Title.ScrLang;}
            set{_Title.ScrLang = value;}
        }
        public string LangScr
        {
            get{return _Lang.ScrLang;}
            set{ _Lang.ScrLang = value; }
        }
        public string Tags
        {
            get {string sRet="";
                foreach(string s in _Tag)
                    sRet+=(s+"; ");
                return sRet;  }
            set{string sval=value;
                string[] Separators = new string[] { "; ",";"," ;"};
                _Tag.Clear();
                foreach (string s in sval.Split(Separators, System.StringSplitOptions.RemoveEmptyEntries))
                    _Tag.Add(s); }
        }
        public string Themes
        {
            get
            {
                return _Theme.SelectedNameList;
            }
        }
    }

    public class LibPerson : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public LibPerson(string last="",string first="",string middle="",string nick="",string homepages="",string email="",string avtortype="")
        {
            _First =  new LibLang(first);
            _Middle = new LibLang(middle);
            _Last =   new LibLang(last);
            Nick =      (nick == ""      ? string.Empty : nick);
            HomePages = (homepages == "" ? string.Empty : homepages);
            Email =     (email == ""     ? string.Empty : email);
            PersonType = (avtortype == "" ? string.Empty : avtortype);

            NotifyPropertyChanged("ListName");
        }
        public LibLang _First  { get; private set; }
        public LibLang _Middle { get; private set; }
        public LibLang _Last   { get; private set; }
        public string Nick      { get; set; }
        public string HomePages { get; set; }
        public string Email     { get; set; }
        public string PersonType { get; set; }
        public string First
        {
            get {return _First.BookLang; }
            set  
            {
                _First.BookLang = value;
                NotifyPropertyChanged("ListName");
            }
        }
        public string Middle
        {
            get{return _Middle.BookLang;}
            set
            {
                _Middle.BookLang = value; 
                NotifyPropertyChanged("ListName");                 
            }
        }
        public string Last
        {
            get{ return _Last.BookLang; }
            set 
            {
                _Last.BookLang = value;
                NotifyPropertyChanged("ListName");                 
            }
        }
        public string FirstScr
        {
            get{ return _First.ScrLang; }
            set{ _First.ScrLang = value; }
        }
        public string MiddleScr
        {
            get{return _Middle.ScrLang;}
            set{ _Middle.ScrLang = value; }
        }
        public string LastScr
        {
            get{ return _Last.ScrLang; }
            set { _Last.ScrLang = value;}
        }

        public string ListName
        {
            get { return this.Last != string.Empty ? (this.Last + " " + 
                            ((this.First.Trim().Length  > 0)? (this.First.Substring(1, 1)  + "."):"") + 
                            ((this.Middle.Trim().Length > 0)? (this.Middle.Substring(1, 1) + "."):"")     ) 
                                    : (this.Nick == string.Empty ? "Unknown" : this.Nick); }
        }
        //public int    indx      { get; set; }               
    
    }

     public class LibLang
     {
         public LibLang(string name = "", string scrname = "")
         {
             BookLang = (name == "" ? string.Empty : name);
             ScrLang = (scrname == "" ? string.Empty : scrname);
         }
         public string BookLang    { get; set; }
         public string ScrLang { get; set; }
     }
    
    
    public class LibAnnot
    {
        public LibAnnot(string text="")
        {
            Text = (text == "" ? string.Empty : text);
        }
        public string Text { get; set; }
    }


    public class LibCover : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public LibCover()
        {
            //Base64 = string.Empty;
            BinaryData = null;
        }
        //public string Base64 { get; set; }
        //public ImageSource CoverIS { get; set; }
        public Byte[] BinaryData { get; set; }

        public ImageSource Cover
        {
            get
            {
                BitmapImage bmpImage;
                if (BinaryData != null)
                {
                    bmpImage  = new BitmapImage();
                    MemoryStream strm = new MemoryStream(BinaryData);
                     bmpImage.BeginInit();
                    strm.Seek(0, SeekOrigin.Begin);
                    bmpImage.StreamSource = strm;
                    bmpImage.EndInit();
                 }
                else
                {
                    bmpImage = new BitmapImage( new Uri("dat\\unnamed.jpg", UriKind.Relative));
                }
                return bmpImage;
            }   
        }

        public void FillFromFile(string fileName)
        {
            FileStream fs=new FileStream(fileName,FileMode.Open);
            BinaryData=new Byte[fs.Length];
            fs.Read(BinaryData, 0, BinaryData.Length);
            fs.Close();
            NotifyPropertyChanged("Cover");   
        }

        public void Clear()
        {
            BinaryData = null;
            NotifyPropertyChanged("Cover");  
            
        }
    }


    public class LibSequence : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public LibSequence(LibSequence parent, string name = "", int? num = null )
        {
            _Name=new LibLang (name);
            _n_Num=num;
            SubSequence = new ObservableCollection<LibSequence>();
            Parent=parent;
            _s_Num = string.Empty;
        }
        public LibSequence Parent {get;private set;}
        public LibLang _Name { get; private set; }
        public int? _n_Num { get; set; }
        public string _s_Num {get;set;}
        public ObservableCollection<LibSequence> SubSequence { get; private set; }
        public string Name
        {
            get { return (_Name.BookLang==string.Empty ? "Empty":_Name.BookLang) ; }
            set 
            { 
                _Name.BookLang = value;
                NotifyPropertyChanged("Name");   
            }
        }
        public string NameScr
        {
            get { return _Name.ScrLang ; }
            set 
            { 
                _Name.ScrLang = value;
                NotifyPropertyChanged("NameScr"); 
            }
        }
        public string s_Num
        {
            get { return _s_Num; }
            set
            {
                _s_Num = value;
                NotifyPropertyChanged("s_Num");
            }
        }
        public int? n_Num
        {
            get { return _n_Num; }
            set
            {
                _n_Num = value;
                if (string.IsNullOrEmpty(_s_Num))
                {
                    _s_Num = (_n_Num==null?string.Empty:  _n_Num.ToString());
                    NotifyPropertyChanged("s_Num");
                }
                NotifyPropertyChanged("n_Num");
            }
        }
    }

    public class LibFileInf
    {
        public LibFileInf()
        {
            Creator = new ObservableCollection<LibPerson>();
            DateCreate=null;
            Id=string.Empty;
            Version=string.Empty;
            SCR_URL=new List<string>();
            OSR=string.Empty;
        }
        public ObservableCollection<LibPerson> Creator { get; private set; }
        public DateTime? DateCreate {get;set;}
        public string Id {get;set;}
        public string Version {get;set;}
        public List<string> SCR_URL {get;set;}
        public string OSR {get;set;}

        
    }

    public class LibPublisher
    {
        public LibPublisher()
        {
            Translator = new ObservableCollection<LibPerson>();
            Painter = new ObservableCollection<LibPerson>(); 
            Publisher=new List<string>();
            City=string.Empty;
            Year=null;
            Pages=null;
            ISBN=new List<string>();
            UDK=string.Empty;
            BBK=string.Empty;
            GRNTI=string.Empty;
        }
        public string City {get;set;}
        public int? Year {get;set;}
        public List<string> ISBN {get;private set;}
        public List<string> Publisher {get;private set;}
        public ObservableCollection<LibPerson> Translator { get; private set; }
        public ObservableCollection<LibPerson> Painter { get; private set; }
        public int? Pages {get;set;}
        public string UDK {get;set;}
        public string BBK {get;set;}
        public string GRNTI {get;set;}
    }
}
